package server.business.service.Impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import server.business.mapper.*;
import server.business.pojo.*;
import server.business.service.BloodInBoundService;
import server.business.service.BloodInformationService;
import server.business.service.InboundReviewService;
import server.business.service.InboundStateService;
import server.business.utils.UUIDUtils;
import server.business.vo.Result;
import server.business.vo.ResultExpand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author ccb
 * @date 2022/08/11
 */

@Service("bloodInBoundService")
public class BloodInBoundServiceImpl extends ServiceImpl<BloodInBoundMapper, BloodInBoundData> implements BloodInBoundService {

    @Autowired
    private BloodInBoundMapper bloodInBoundMapper;
    @Autowired
    private BloodInBoundService bloodInBoundService;
    @Autowired
    private BloodInformationService bloodInformationService;
    @Autowired
    private BloodInformationMapper bloodInformationMapper;
    @Autowired
    private InboundReviewMapper inboundReviewMapper;
    @Autowired
    private InboundReviewService inboundReviewService;
    @Autowired
    private InboundStateMapper inboundStateMapper;
    @Autowired
    private InboundStateService inboundStateService;
    @Autowired
    private StateMapper stateMapper;


    /**
     * 选择页面
     *
     * @param currentPage 当前页面
     * @param pageSize    页面大小
     * @return {@link IPage}<{@link BloodInBoundData}>
     */
    public IPage<BloodInBoundData> selectByPage(int currentPage, int pageSize) {
        Page<BloodInBoundData> page = new Page<>(currentPage, pageSize);
        IPage<BloodInBoundData> bloodInBoundDataIPage = bloodInBoundMapper.selectPage(page, null);
        return bloodInBoundDataIPage;
    }


    /**
     * 查询数据
     *
     * @return {@link List}<{@link BloodInBoundData}>
     */
    public List<BloodInBoundData> queryData(){
        List<BloodInBoundData> list = bloodInBoundService.list();
        return list;
    }

    /**
     * 增加血液入库信息
     *
     * @param json json
     * @return {@link Result}
     */
    @Transactional(rollbackFor = Exception.class)
    public Result addBloodInBound(String json) {
        //获取入库信息
        JSONObject jsonObject = JSON.parseObject(json);
        BloodInBoundData bloodInBoundData = jsonObject.getObject("addInBound", BloodInBoundData.class);

        //血液状态为"入库”的代码
        QueryWrapper<State> stateQueryWrapper = new QueryWrapper<>();
        stateQueryWrapper.eq("state", "入库");
        State bloodState = stateMapper.selectOne(stateQueryWrapper);
        String bloodStateCode = bloodState.getCode();

        //获取入库的血液信息
        BloodInformation bloodInformation = jsonObject.getObject("bloodMessage", BloodInformation.class);
        bloodInformation.setGmtCreate(new Date());
        bloodInformation.setGmtModified(new Date());
        bloodInformation.setBloodId(UUIDUtils.getUUID());
        bloodInformation.setState(bloodStateCode);
        bloodInformation.setBatchNumber(123456L);    //暂定

        //存入血液信息表，状态为入库
        boolean successIn = bloodInformationService.save(bloodInformation);

        //获取血液信息表中的id
        Long bloodId = bloodInformation.getId();
        bloodInformation = bloodInformationMapper.selectById(bloodId);

        bloodInBoundData.setBloodMessage(JSON.toJSONString(bloodInformation));
        bloodInBoundData.setBloodId(bloodId + "");
        bloodInBoundData.setGmtCreate(new Date());
        bloodInBoundData.setGmtModified(new Date());
        bloodInBoundData.setNumber(UUIDUtils.getUUID());    //单据号
        bloodInBoundData.setBatchNumber(Long.parseLong(UUIDUtils.getUUID()));   //批次号
        bloodInBoundData.setSerialNumber(UUIDUtils.getUUID());
        bloodInBoundData.setInboundTime(new Date());
        //存入血液入库表
        boolean successBlood = bloodInBoundService.save(bloodInBoundData);

        //在入库审核表中新增记录，状态为“入库等待审核”
        //获取“入库等待审核”的代码
        QueryWrapper<InboundState> inboundStateQueryWrapper = new QueryWrapper<>();
        inboundStateQueryWrapper.eq("name", "入库等待审核");
        InboundState inboundState = inboundStateMapper.selectOne(inboundStateQueryWrapper);
        System.out.println(inboundState);
        //新建InboundReview对象
        InboundReview newInboundReview = new InboundReview();
        newInboundReview.setInboundId(bloodInBoundData.getId());
        newInboundReview.setApplicantId(Long.parseLong(bloodInBoundData.getOperatorId()));
        newInboundReview.setApplyTime(bloodInBoundData.getInboundTime());
        newInboundReview.setState(inboundState.getCode());
        boolean successReview = inboundReviewService.save(newInboundReview);

        //出错回退
        if (successBlood == false || successIn == false || successReview == false) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
        Result result = new Result();
        result.setCode("200");
        result.setMsg("登记血液信息成功");
        return result;
    }

    /**
     * 搜索血液入库信息
     *
     * @param request  请求
     * @param response 响应
     * @return {@link ResultExpand}
     */
    public ResultExpand searchBloodInBound(HttpServletRequest request, HttpServletResponse response) {
        //接收前端获取的参数
        String number = request.getParameter("number");
        String batchNumber = request.getParameter("batchNumber");
        String bloodNumber = request.getParameter("bloodNumber");
        String bloodSource = request.getParameter("bloodSource");
        String operator = request.getParameter("operator");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        Integer currentPage = Integer.parseInt(request.getParameter("currentPage"));
        Integer pageSize = Integer.parseInt(request.getParameter("pageSize"));
        //创建分页对象
//        IPage<BloodInBoundData> page = new Page<>(currentPage, pageSize);
        //创建查询条件
        QueryWrapper<BloodInBoundData> queryWrapper = new QueryWrapper<>();
        if (number != "")
            queryWrapper.like("`number`", number);
        if (batchNumber != "")
            queryWrapper.eq("batch_number", batchNumber);
        if (bloodNumber != "")
            queryWrapper.eq("blood_number", bloodNumber);
        if (bloodSource != "")
            queryWrapper.eq("blood_source", bloodSource);
        if (operator != "")
            queryWrapper.eq("operator", operator);
        if (startTime != "")
            queryWrapper.ge("inbound_time", startTime);
        if (endTime != "")
            queryWrapper.le("inbound_time", endTime + " 23:59:59");
        //查询数据库
//        bloodInBoundService.page(page, queryWrapper);
        IPage<BloodInBoundData> page = bloodInBoundMapper.selectInboundpage(
                new Page<>(currentPage, pageSize),  queryWrapper
        );
        //返回的数据
        ResultExpand resultExpand = new ResultExpand();
        resultExpand.setCurrent(currentPage).setPageSize(pageSize).setTotal(page.getTotal()).setPages(page.getPages());
        resultExpand.setCode("200");
        resultExpand.setMsg("搜索成功");
        resultExpand.setData(page.getRecords());
        System.out.println(page.getRecords());
        return resultExpand;
    }


    /**
     * 查看血液信息
     *
     * @param request  请求
     * @param response 响应
     * @return {@link ResultExpand}
     */
    public Result getBloodInformation(HttpServletRequest request, HttpServletResponse response) {
        String bloodId = request.getParameter("bloodId");
        System.out.println(bloodId);
        QueryWrapper<BloodInformation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", bloodId);

//        BloodInformation bloodInformation = bloodInformationMapper.selectOne(queryWrapper);

        IPage<BloodInformation> page = bloodInformationMapper.selectBloodpage(
                new Page<>(1, 1),  queryWrapper
        );
        System.out.println(page.getRecords());
        BloodInformation bloodInformation = page.getRecords().get(0);
//        System.out.println(bloodInformation);
        Result result = new Result();
        result.setCode("200");
        result.setMsg("搜索成功");
        result.setData(bloodInformation);
        return result;
    }


    public Result reviewBloodInBound(HttpServletRequest request, HttpServletResponse response) {
        //血液id
        String bloodId = request.getParameter("BloodId");
        //入库id
        String inBoundId = request.getParameter("InBoundId");
        //复核人工号
        String reviewerId = request.getParameter("reviewerId");

        //查询“入库通过”状态的代码 inboundStateId
        QueryWrapper<InboundState> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "入库通过");
        InboundState inboundState = inboundStateMapper.selectOne(queryWrapper);
        String inboundStateCode = inboundState.getCode();

        //修改inbound_review审批表的状态
        UpdateWrapper<InboundReview> inboundReviewUpdateWrapper = new UpdateWrapper<>();
        inboundReviewUpdateWrapper.eq("inbound_id", inBoundId);
        inboundReviewUpdateWrapper.set("state", inboundStateCode);
        inboundReviewUpdateWrapper.set("reviewer_id", reviewerId);
        inboundReviewUpdateWrapper.set("review_time", new Date());
        inboundReviewMapper.update(null, inboundReviewUpdateWrapper);

        //修改血液信息表Blood_information的状态
        //获取血液在库的状态代码
        QueryWrapper<State> stateQueryWrapper = new QueryWrapper<>();
        stateQueryWrapper.eq("state", "在库");
        State bloodState = stateMapper.selectOne(stateQueryWrapper);
        String bloodStateCode = bloodState.getCode();

        //修改血液信息的状态为“在库"
        UpdateWrapper<BloodInformation> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", bloodId);
        updateWrapper.set("state", bloodStateCode);
        bloodInformationMapper.update(null, updateWrapper);
        Result result = new Result();
        result.setCode("200");
        result.setMsg("入库成功");
        return result;
    }

    public Result cancelBloodInBound(HttpServletRequest request, HttpServletResponse response) {
        //血液id
        String bloodId = request.getParameter("BloodId");
        //入库id
        String inBoundId = request.getParameter("InBoundId");

        //查询“入库驳回”状态的代码 inboundStateId
        QueryWrapper<InboundState> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "入库驳回");
        InboundState inboundState = inboundStateMapper.selectOne(queryWrapper);
        String inboundStateCode = inboundState.getCode();

        //修改inbound_review审批表的状态
        UpdateWrapper<InboundReview> inboundReviewUpdateWrapper = new UpdateWrapper<>();
        inboundReviewUpdateWrapper.eq("inbound_id", inBoundId);
        inboundReviewUpdateWrapper.set("state", inboundStateCode);
        inboundReviewMapper.update(null, inboundReviewUpdateWrapper);

        //修改血液信息表Blood_information的状态
        //获取血液在库的状态代码
        QueryWrapper<State> stateQueryWrapper = new QueryWrapper<>();
        stateQueryWrapper.eq("state", "取消入库");
        State bloodState = stateMapper.selectOne(stateQueryWrapper);
        String bloodStateCode = bloodState.getCode();
        //修改血液信息的状态为“在库"
        UpdateWrapper<BloodInformation> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", bloodId);
        updateWrapper.set("state", bloodStateCode);
        bloodInformationMapper.update(null, updateWrapper);
        Result result = new Result();
        result.setCode("200");
        result.setMsg("入库成功");
        return result;
    }

    public void downloadExcel(HttpServletRequest request, HttpServletResponse response) {
        //接收前端获取的参数
        String number = request.getParameter("number");
        String batchNumber = request.getParameter("batchNumber");
        String bloodNumber = request.getParameter("bloodNumber");
        String bloodSource = request.getParameter("bloodSource");
        String operator = request.getParameter("operator");
        String startTime = request.getParameter("startTime");
        String endTime = request.getParameter("endTime");
        //创建分页对象
//        IPage<BloodInBoundData> page = new Page<>(currentPage, pageSize);

        try {
            String filename = "入库信息";
            String userAgent = request.getHeader("User-Agent");
            if(userAgent.contains("MSIE")||userAgent.contains("Trident")){
                filename = URLEncoder.encode(filename,"UTF-8");
            }else {
                filename = new String(filename.getBytes("UTF-8"),"ISO-8859-1");
            }
            response.setContentType("application/json.ms-exce");
            response.setCharacterEncoding("utf-8");
            response.addHeader("Content-Disposition","filename = " + filename + ".xlsx");
            //创建查询条件
            QueryWrapper<BloodInBoundData> queryWrapper = new QueryWrapper<>();
            if (number != "")
                queryWrapper.like("`number`", number);
            if (batchNumber != "")
                queryWrapper.eq("batch_number", batchNumber);
            if (bloodNumber != "")
                queryWrapper.eq("blood_number", bloodNumber);
            if (bloodSource != "")
                queryWrapper.eq("blood_source", bloodSource);
            if (operator != "")
                queryWrapper.eq("operator", operator);
            if (startTime != "")
                queryWrapper.ge("inbound_time", startTime);
            if (endTime != "")
                queryWrapper.le("inbound_time", endTime + " 23:59:59");
            List<BloodInBoundData> bloodInBoundDataList = bloodInBoundService.list(queryWrapper);
            EasyExcel.write(response.getOutputStream(), BloodInBoundData.class).sheet("sheet").doWrite(bloodInBoundDataList);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    /**
     * fzx
     * @param bloodId
     * @return
     */
    public List<Map<String, Object>> getBloodInList(String bloodId) {
        QueryWrapper<BloodInBoundData> wrapperOut = new QueryWrapper<>();
        wrapperOut
                .lambda()
                .eq(BloodInBoundData::getBloodId,bloodId)
                .select(BloodInBoundData::getNumber,
                        BloodInBoundData::getBatchNumber,
                        BloodInBoundData::getNumber,
                        BloodInBoundData::getBloodSource,
                        BloodInBoundData::getOperator,
                        BloodInBoundData::getOperatorId,
                        BloodInBoundData::getBloodNumber
                );
        List<Map<String, Object>> listOutId = listMaps(wrapperOut);
        return listOutId;
    }

}
